﻿using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace OneStationFile.DAL
{
    /// <summary>
    /// Nhibernate辅助类
    /// </summary>
    class FluentNHibernateHelper
    {
        private static ISessionFactory _sessionFactory;
        private static ISession _session;
        private static object _objLock = new object();
        public static readonly string CurrentSessionKey = "NHibernate.Context.WebSessionContext.SessionFactoryMapKey";

        private FluentNHibernateHelper()
        {

        }
        /// <summary>
        /// 创建ISessionFactory
        /// </summary>
        /// <returns></returns>
        public static void GetSessionFactory()
        {
            if (_sessionFactory == null)
            {
                lock (_objLock)
                {
                    if (_sessionFactory == null)
                    {
                        string str = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.176)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)));User Id=osf;Password=osf;Persist Security Info=True;";
                        //string str = "Data Source=192.168.0.176:1521/ORCL;User Id=cqscpipe;Password=cqscpipe;Persist Security Info=True;";
                        //配置ISessionFactory     
                        _sessionFactory = Fluently.Configure()
                        //数据库配置
                        .Database(
                            //OracleDataClientConfiguration.Oracle10
                            //OracleManagedDataClientConfiguration.Oracle10
                            OracleClientConfiguration.Oracle10
                            .Provider<NHibernate.Connection.DriverConnectionProvider>()
                            //.ConnectionString(
                            //   c => c.Server(".")
                            // .Password("sa")
                            // .Username("sa")
                            // )
                            .ConnectionString(str)//连接字符串
                            .Dialect<NHibernate.Dialect.Oracle10gDialect>()
                            .Driver<NHibernate.Driver.OracleDataClientDriver>()
                            .UseOuterJoin()
                            .ShowSql()//是否显示sql
                            .QuerySubstitutions("true 1, false 0, yes 'Y', no 'N'")
                            .DefaultSchema("osf")//默认的表前缀，也就是当前用户名

                        )
                        //映射程序集
                        .Mappings(m =>
                        //m.FluentMappings.AddFromAssembly(System.Reflection.Assembly.Load("Model")).ExportTo("c:/")
                        {
                            m.FluentMappings.AddFromAssemblyOf<Model.TestMap>();//添加映射文件，从ClassMap中自动添加

                            m.FluentMappings
                            .AddFromAssembly(System.Reflection.Assembly.Load("OneStationFile.Model"))
                            .Conventions.AddFromAssemblyOf<EnumConvention>()
                            .ExportTo("c:/xml/");//.Conventions.AddFromAssemblyOf<EnumConvention>()
                            //m.HbmMappings.AddFromAssemblyOf<Model.TestMap>();//添加映射文件（hbm）
                        }
                        )
                         //生成数据库架构
                         /*
                          SchemaUpdate Execute 用来更新数据库表结构,没有就创建新的，有就更新，但是不会删除现有的结构（字段）和数据
                          SchemaExport Create 先删除表结构，再重新创建新的数据库表结构，连同数据一起删除。
                          SchemaExport Drop 删除表结构。
                          */
                         .ExposeConfiguration(p=>new SchemaUpdate(p).Execute(true,true))//更新数据库表结构，如果表存在，不做任何操作。
                         //.ExposeConfiguration(p => new SchemaExport(p).Execute(true,true,false))// false     .Create(true, true)
                        .BuildSessionFactory();
                    }
                }
            }
            //return _sessionFactory;

        }
    
        /// <summary>
        /// 重置Session
        /// </summary>
        /// <returns></returns>
        public static ISession ResetSession()
        {
            if (_session.IsOpen)
                _session.Close();
            _session = _sessionFactory.OpenSession();
            return _session;
        }
        /// <summary>
        /// 打开ISession
        /// </summary>
        /// <returns></returns>
        public static ISession GetSession()
        {
            GetSessionFactory();
            if (_session == null)
            {
                lock (_objLock)
                {
                    if (_session == null)
                    {
                        //_session = _sessionFactory.OpenSession();
                        _session = _sessionFactory.OpenSession();
                        //_session.FlushMode = FlushMode.Auto;
                    }
                }
            }
            return _session;
            //var ht = HttpContext.Current.Items[CurrentSessionKey] as System.Collections.Hashtable;
            //ISession currentSession = HttpContext.Current.Items[CurrentSessionKey] as ISession;
            ////ISession currentSession = ht[_sessionFactory] as ISession;
            //if (currentSession == null)
            //{
            //    currentSession = _sessionFactory.OpenSession();
            //    HttpContext.Current.Items[CurrentSessionKey] = currentSession;
            //    //NHibernate.Context.WebSessionContext.Bind(currentSession);//还是用NHibernate自带的方法将Session绑定到HttpContext.Current上.
            //}
            //return currentSession;

        }


        /// <summary>
        /// 关闭Session
        /// </summary>
        public static void CloseSession()
        {
            _session.Flush();
            _session.Clear();
            _session.Close();
            //var ht = HttpContext.Current.Items[CurrentSessionKey] as System.Collections.Hashtable;
            //ISession currentSession = ht[SessionFactory] as ISession;
            //var currentSession = NHibernate.Context.WebSessionContext.Unbind(_sessionFactory);　//从HttpContext.Current中卸载Session,并返回当前Session
            //if (currentSession == null)
            //{
            //    //　No　current　session　　　
            //    return;
            //}
            //currentSession.Close();
            //HttpContext.Current.Items.Remove(CurrentSessionKey);
        }

    }
}

